package tcp

import (
	"lnzw/engine/log"
	"net"
	"sync"

	"go.uber.org/zap"
)

type TcpServer struct {
	*TcpSocket
	conns   sync.Map
	address string
}

func NewServer() *TcpServer {
	return &TcpServer{
		TcpSocket: &TcpSocket{},
	}
}

func (s *TcpServer) BindAddress(address string) *TcpServer {
	s.address = address
	return s
}

func (s *TcpServer) Start() {
	log.Logger.Info("server start. listnen address:", zap.String("address", s.address))
	listner, err := net.Listen("tcp", s.address)
	if err != nil {
		log.Logger.Error("listen failed", zap.Error(err))
		panic(err)
	}
	//检查encoder decoder
	if s.encoder == nil || s.decoder == nil {
		log.Logger.Error("encoder or decoder is nil")
		panic("encoder or decoder is nil")
	}
	//检查socketHandle
	if s.socketHandle == nil {
		log.Logger.Error("socketHandle is nil")
		panic("socketHandle is nil")
	}
	defer listner.Close()

	for {
		conn, err := listner.Accept()
		if err != nil {
			log.Logger.Error("accept failed", zap.Error(err))
			continue
		}
		client := buildClient(conn, s)
		s.conns.Store(client.id, client)
		s.socketHandle.OnConnect(client)
		client.StartWork()
	}
}

func (s *TcpServer) OnClose(client *SocketClient) {
	s.TcpSocket.OnClose(client)
	s.conns.Delete(client.id)
	log.Logger.Info("client closed, remove it", zap.Int64("id", client.id))

}

func (s *TcpServer) Stop() {
	log.Logger.Info("server stop")
}
